﻿using LibPlug.Model;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;

namespace BiliBiliLiveDanMuTool.Plugins
{
    /// <summary>
    /// 基础插件管理类
    /// </summary>
    public class BasePluginsManager <T> where T :class
    {
        /// <summary>
        /// 插件列表
        /// </summary>
        public List<T> Plugins { get; }
        /// <summary>
        /// 插件信息列表
        /// </summary>
        public List<PluginsInfoAttribute>  Infos{ get;}

        private Type m_interFace;

        public BasePluginsManager()
        {
            Plugins = new List<T>();
            Infos = new List<PluginsInfoAttribute>();
            m_interFace = typeof(T);
        }

        /// <summary>
        /// 加载所有插件
        /// </summary>
        /// <returns></returns>
        public int LoadPlugins()
        {
            Plugins.Clear();
            Infos.Clear();

            if (!Directory.Exists(Environment.CurrentDirectory + @"\Plugins")) return 0;
            string[] _files = Directory.GetFiles(Environment.CurrentDirectory + @"\Plugins");
            PluginsInfoAttribute _info = null;
            
            foreach(var _file in _files)
            {
                string _ext = Path.GetExtension(_file);
                if (!_ext.Equals(".dll")) continue;

                Assembly _asm = Assembly.UnsafeLoadFrom(_file);
                Type[] _types = _asm.GetTypes(); // 分析程序集所有对象
                foreach(var t in _types)
                {
                    if(t.GetInterface(m_interFace.FullName) != null)
                    {
                        T _plug = (T)_asm.CreateInstance(t.FullName);
                        Plugins.Add(_plug);

                        _info = t.GetCustomAttribute(typeof(PluginsInfoAttribute)) as PluginsInfoAttribute;
                        Infos.Add(_info);
                        CallBack();
                    }
                }
            }

            if (Plugins != null) return Plugins.Count;
            else return 0;
        }

        protected virtual void CallBack() { }
    }
}
